﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using eeenno.ReaderEngine;
using eeenno.ReaderEngine.Utilities;

namespace eeenno.SpeeedReaderUI.Forms
{
    public partial class LoginForm : Form
    {
        private delegate void _updateStatusBarCallback(string value);
        private delegate void _loginPanelCloseCallback();
        private delegate string[] _getCredentialsCallback();
        private delegate void _enableWaitCursorCallback(bool enable);
        private delegate bool _isCheckedCheckBoxCallback();
        private delegate bool _isCheckedAutoLoginCallback();
        private delegate void _enableFormCallback(bool enable);
        private delegate bool _isOfflineModeChecked();

        public LoginForm()
        {
            InitializeComponent();
            label_version.Text = "Speeed Reader v" + SpeeedReader.MajorVersion() + "." + SpeeedReader.MinorVersion();
            //preload username and password if saved in registry
            //remember me was checked previosuly
            string username = Settings.username;
            string password = Settings.password;
            menuItem_login_auto.Checked = Settings.auto_login;
            //offline mode depends on a cache being present, if one is not present do not go into 
            //offline mode
            if (SpeeedReader.DoesCacheExist())
            {
                menuItem_login_offline.Enabled = true;
                menuItem_login_offline.Checked = Settings.offline_mode_enabled;
            }
            else
            {
                menuItem_login_offline.Checked = menuItem_login_offline.Enabled = false;
            }
            menuItem_login_offline.Checked = Settings.offline_mode_enabled;
            if (username != null && password != null)
            {
                if (username.Length > 0 && password.Length > 0)
                {
                    textBox_username.Text = username;
                    textBox_password.Text = password;
                    menuItem_login_auto.Enabled = menuItem_remember_me.Checked = true;

                    if (Settings.auto_login)
                    {
                        menuItem_login_Click(this, EventArgs.Empty);
                    }
                }
            }            
        }

        #region User interface action handlers

        private void menuItem_about_Click(object sender, EventArgs e)
        {
            AboutForm about_form = new AboutForm(0);
            about_form.Show();
        }

        private void menuItem_appearance_Click(object sender, EventArgs e)
        {
            SettingsAppearanceForm form = new SettingsAppearanceForm();
            form.ShowDialog();            
            form.Dispose();
        }

        private void menuItem_behavior_Click(object sender, EventArgs e)
        {
            int duration = Settings.refresh_duration;
            bool hide = Settings.hide_read_items;
            SettingsBehaviorForm form = new SettingsBehaviorForm();
            form.ShowDialog();           
            form.Dispose();
        }

        private void menuItem_connectivity_Click(object sender, EventArgs e)
        {
            SettingsConnectivityForm form = new SettingsConnectivityForm();
            form.ShowDialog();
            form.Dispose();
        }

        private void menuItem_social_Click(object sender, EventArgs e)
        {
            SettingsSocialForm form = new SettingsSocialForm();
            form.ShowDialog();
            form.Dispose();
        }

        private void menuItem_login_Click(object sender, EventArgs e)
        {
            if (textBox_username.Text.Length < 1 || textBox_password.Text.Length < 1)
            {
                MainForm.DisplayMessageBox("Please enter username/password");
            }
            else
            {
                ThreadFactory.DoWork(Login);
            }
        }

        private void menuItem_exit_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        }
        #endregion

        #region User Interface callbacks

        private bool IsOfflineModeChecked()
        {
            if (this.InvokeRequired)
            {
                return (bool)this.Invoke(new _isOfflineModeChecked(IsOfflineModeChecked));
            }
            else
            {
                return menuItem_login_offline.Checked;
            }
        }

        private void EnableFormCallback(bool enable)
        {
            if (textBox_username.InvokeRequired)
            {
                textBox_username.Invoke(new _enableFormCallback(EnableFormCallback), enable);
            }
            else
            {
                textBox_username.Enabled = enable;
                textBox_password.Enabled = enable;
                menuItem_login.Enabled = enable;
                menuItem_remember_me.Enabled = enable;               
                menuItem_login_auto.Enabled = enable;
                if (SpeeedReader.DoesCacheExist())
                {
                    menuItem_login_offline.Enabled = enable;
                }
            }
        }        

        private string[] GetCredentialsCallback()
        {
            if (textBox_username.InvokeRequired)
            {
                return (string[])textBox_username.Invoke(new _getCredentialsCallback(GetCredentialsCallback));
            }
            else
            {
                return new string[] { textBox_username.Text, textBox_password.Text };
            }
        }

        private void EnableWaitCursorCallback(bool enable)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new _enableWaitCursorCallback(EnableWaitCursorCallback),
                    enable);
            }
            else
            {
                if (!enable)
                {
                    Cursor.Current = Cursors.WaitCursor;
                }
                else
                {
                    Cursor.Current = Cursors.Default;
                }
            }
        }

        private void LoginPanelCloseCallback()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new _loginPanelCloseCallback(LoginPanelCloseCallback));
            }
            else
            {
                this.DialogResult = DialogResult.Yes;
                this.Close();
            }
        }

        private bool IsCheckedCheckBoxCallback()
        {
            if (this.InvokeRequired)
            {

                return (bool)this.Invoke(new _isCheckedCheckBoxCallback(IsCheckedCheckBoxCallback));
            }
            else
            {
                return menuItem_remember_me.Checked;
            }
        }

        private bool IsCheckedAutoLoginCallback()
        {
            if (this.InvokeRequired)
            {

                return (bool)this.Invoke(new _isCheckedAutoLoginCallback(IsCheckedAutoLoginCallback));
            }
            else
            {
                return menuItem_login_auto.Checked;
            }
        }

        #endregion

        #region Logic for interacting with Google Reader

        /// <summary>
        /// Uses GRE to request authentication to Google Reader server
        /// </summary>
        private void Login(Object stateInfo)
        {
            EnableWaitCursorCallback(false);
            EnableFormCallback(false);
            Settings.offline_mode_enabled = IsOfflineModeChecked();
            
            if (!IsOfflineModeChecked() && SpeeedReader.Login(GetCredentialsCallback()))
            {
                //check to see if the remember me checkbox is checked
                //if so, save the username and password to the registry
                if (IsCheckedCheckBoxCallback())
                {
                    string[] cred = GetCredentialsCallback();
                    Settings.username = cred[0];
                    Settings.password = cred[1];
                    Settings.auto_login = IsCheckedAutoLoginCallback();
                    Settings.WriteSettings();
                }

                EnableWaitCursorCallback(true);
                LoginPanelCloseCallback();
            }
            else if (IsOfflineModeChecked())
            {                
                Settings.WriteSettings();
                EnableWaitCursorCallback(true);
                EnableFormCallback(true);
                LoginPanelCloseCallback();
            }
            else
            {
                MainForm.DisplayMessageBox("Unable to login, try again");
                EnableWaitCursorCallback(true);
                EnableFormCallback(true);
            }            
        }

        #endregion           

        private void menuItem_remember_me_Click(object sender, EventArgs e)
        {
            if (menuItem_remember_me.Checked)
            {
                menuItem_remember_me.Checked = false;
                menuItem_login_auto.Enabled = false;
                menuItem_login_auto.Checked = false;
            }
            else
            {
                menuItem_remember_me.Checked = true;
                menuItem_login_auto.Enabled = true;                
            }
        }

        private void menuItem_login_offline_Click(object sender, EventArgs e)
        {
            if (menuItem_login_offline.Checked)
            {
                menuItem_login_offline.Checked = false;
            }
            else
            {
                menuItem_login_offline.Checked = true;
            }
        }

        private void menuItem_login_auto_Click(object sender, EventArgs e)
        {
            if (menuItem_login_auto.Checked)
            {
                menuItem_login_auto.Checked = false;
            }
            else
            {
                menuItem_login_auto.Checked = true;
            }
        }

    }
}